import 'package:shared_preferences/shared_preferences.dart';
import 'dart:convert';
import '../exceptions/app_exceptions.dart';
import '../utils/logger.dart';

class SharedPrefsStorage {
  static SharedPrefsStorage? _instance;
  static SharedPrefsStorage get instance => _instance ??= SharedPrefsStorage._internal();
  
  SharedPreferences? _prefs;
  
  SharedPrefsStorage._internal();

  Future<void> init() async {
    try {
      _prefs = await SharedPreferences.getInstance();
      AppLogger.info('SharedPreferences initialized');
    } catch (e) {
      AppLogger.error('Failed to initialize SharedPreferences', e);
      throw StorageException(
        message: 'Failed to initialize SharedPreferences',
        details: e.toString(),
      );
    }
  }

  // 确保已初始化
  void _ensureInitialized() {
    if (_prefs == null) {
      throw StorageException(
        message: 'SharedPreferences not initialized. Call init() first.',
      );
    }
  }

  // 存储字符串
  Future<bool> setString(String key, String value) async {
    try {
      _ensureInitialized();
      final result = await _prefs!.setString(key, value);
      AppLogger.debug('Set string: $key = $value');
      return result;
    } catch (e) {
      AppLogger.error('Failed to set string: $key', e);
      throw StorageException(
        message: 'Failed to set string',
        details: e.toString(),
      );
    }
  }

  // 获取字符串
  String? getString(String key, [String? defaultValue]) {
    try {
      _ensureInitialized();
      final value = _prefs!.getString(key) ?? defaultValue;
      AppLogger.debug('Get string: $key = $value');
      return value;
    } catch (e) {
      AppLogger.error('Failed to get string: $key', e);
      return defaultValue;
    }
  }

  // 存储整数
  Future<bool> setInt(String key, int value) async {
    try {
      _ensureInitialized();
      final result = await _prefs!.setInt(key, value);
      AppLogger.debug('Set int: $key = $value');
      return result;
    } catch (e) {
      AppLogger.error('Failed to set int: $key', e);
      throw StorageException(
        message: 'Failed to set int',
        details: e.toString(),
      );
    }
  }

  // 获取整数
  int? getInt(String key, [int? defaultValue]) {
    try {
      _ensureInitialized();
      final value = _prefs!.getInt(key) ?? defaultValue;
      AppLogger.debug('Get int: $key = $value');
      return value;
    } catch (e) {
      AppLogger.error('Failed to get int: $key', e);
      return defaultValue;
    }
  }

  // 存储浮点数
  Future<bool> setDouble(String key, double value) async {
    try {
      _ensureInitialized();
      final result = await _prefs!.setDouble(key, value);
      AppLogger.debug('Set double: $key = $value');
      return result;
    } catch (e) {
      AppLogger.error('Failed to set double: $key', e);
      throw StorageException(
        message: 'Failed to set double',
        details: e.toString(),
      );
    }
  }

  // 获取浮点数
  double? getDouble(String key, [double? defaultValue]) {
    try {
      _ensureInitialized();
      final value = _prefs!.getDouble(key) ?? defaultValue;
      AppLogger.debug('Get double: $key = $value');
      return value;
    } catch (e) {
      AppLogger.error('Failed to get double: $key', e);
      return defaultValue;
    }
  }

  // 存储布尔值
  Future<bool> setBool(String key, bool value) async {
    try {
      _ensureInitialized();
      final result = await _prefs!.setBool(key, value);
      AppLogger.debug('Set bool: $key = $value');
      return result;
    } catch (e) {
      AppLogger.error('Failed to set bool: $key', e);
      throw StorageException(
        message: 'Failed to set bool',
        details: e.toString(),
      );
    }
  }

  // 获取布尔值
  bool? getBool(String key, [bool? defaultValue]) {
    try {
      _ensureInitialized();
      final value = _prefs!.getBool(key) ?? defaultValue;
      AppLogger.debug('Get bool: $key = $value');
      return value;
    } catch (e) {
      AppLogger.error('Failed to get bool: $key', e);
      return defaultValue;
    }
  }

  // 存储字符串列表
  Future<bool> setStringList(String key, List<String> value) async {
    try {
      _ensureInitialized();
      final result = await _prefs!.setStringList(key, value);
      AppLogger.debug('Set string list: $key = $value');
      return result;
    } catch (e) {
      AppLogger.error('Failed to set string list: $key', e);
      throw StorageException(
        message: 'Failed to set string list',
        details: e.toString(),
      );
    }
  }

  // 获取字符串列表
  List<String>? getStringList(String key, [List<String>? defaultValue]) {
    try {
      _ensureInitialized();
      final value = _prefs!.getStringList(key) ?? defaultValue;
      AppLogger.debug('Get string list: $key = $value');
      return value;
    } catch (e) {
      AppLogger.error('Failed to get string list: $key', e);
      return defaultValue;
    }
  }

  // 存储对象(JSON)
  Future<bool> setObject(String key, Map<String, dynamic> value) async {
    try {
      _ensureInitialized();
      final jsonString = jsonEncode(value);
      final result = await _prefs!.setString(key, jsonString);
      AppLogger.debug('Set object: $key = $value');
      return result;
    } catch (e) {
      AppLogger.error('Failed to set object: $key', e);
      throw StorageException(
        message: 'Failed to set object',
        details: e.toString(),
      );
    }
  }

  // 获取对象(JSON)
  Map<String, dynamic>? getObject(String key, [Map<String, dynamic>? defaultValue]) {
    try {
      _ensureInitialized();
      final jsonString = _prefs!.getString(key);
      if (jsonString == null) {
        return defaultValue;
      }
      final value = jsonDecode(jsonString) as Map<String, dynamic>;
      AppLogger.debug('Get object: $key = $value');
      return value;
    } catch (e) {
      AppLogger.error('Failed to get object: $key', e);
      return defaultValue;
    }
  }

  // 存储对象列表(JSON)
  Future<bool> setObjectList(String key, List<Map<String, dynamic>> value) async {
    try {
      _ensureInitialized();
      final jsonString = jsonEncode(value);
      final result = await _prefs!.setString(key, jsonString);
      AppLogger.debug('Set object list: $key = $value');
      return result;
    } catch (e) {
      AppLogger.error('Failed to set object list: $key', e);
      throw StorageException(
        message: 'Failed to set object list',
        details: e.toString(),
      );
    }
  }

  // 获取对象列表(JSON)
  List<Map<String, dynamic>>? getObjectList(String key, [List<Map<String, dynamic>>? defaultValue]) {
    try {
      _ensureInitialized();
      final jsonString = _prefs!.getString(key);
      if (jsonString == null) {
        return defaultValue;
      }
      final jsonList = jsonDecode(jsonString) as List;
      final value = jsonList.map((item) => item as Map<String, dynamic>).toList();
      AppLogger.debug('Get object list: $key = $value');
      return value;
    } catch (e) {
      AppLogger.error('Failed to get object list: $key', e);
      return defaultValue;
    }
  }

  // 删除键值对
  Future<bool> remove(String key) async {
    try {
      _ensureInitialized();
      final result = await _prefs!.remove(key);
      AppLogger.debug('Remove key: $key');
      return result;
    } catch (e) {
      AppLogger.error('Failed to remove key: $key', e);
      throw StorageException(
        message: 'Failed to remove key',
        details: e.toString(),
      );
    }
  }

  // 检查键是否存在
  bool containsKey(String key) {
    try {
      _ensureInitialized();
      final result = _prefs!.containsKey(key);
      AppLogger.debug('Contains key: $key = $result');
      return result;
    } catch (e) {
      AppLogger.error('Failed to check key: $key', e);
      return false;
    }
  }

  // 获取所有键
  Set<String> getKeys() {
    try {
      _ensureInitialized();
      final keys = _prefs!.getKeys();
      AppLogger.debug('Get all keys: $keys');
      return keys;
    } catch (e) {
      AppLogger.error('Failed to get all keys', e);
      return <String>{};
    }
  }

  // 清除所有数据
  Future<bool> clear() async {
    try {
      _ensureInitialized();
      final result = await _prefs!.clear();
      AppLogger.debug('Clear all data');
      return result;
    } catch (e) {
      AppLogger.error('Failed to clear all data', e);
      throw StorageException(
        message: 'Failed to clear all data',
        details: e.toString(),
      );
    }
  }

  // 重新加载数据
  Future<void> reload() async {
    try {
      _ensureInitialized();
      await _prefs!.reload();
      AppLogger.debug('Reload data');
    } catch (e) {
      AppLogger.error('Failed to reload data', e);
      throw StorageException(
        message: 'Failed to reload data',
        details: e.toString(),
      );
    }
  }

  // 获取数据大小(估算)
  int getSize() {
    try {
      _ensureInitialized();
      int size = 0;
      final keys = _prefs!.getKeys();
      for (final key in keys) {
        final value = _prefs!.get(key);
        if (value != null) {
          size += key.length + value.toString().length;
        }
      }
      AppLogger.debug('Storage size: $size bytes');
      return size;
    } catch (e) {
      AppLogger.error('Failed to get storage size', e);
      return 0;
    }
  }

  // 批量操作
  Future<void> batch(List<Future<bool> Function()> operations) async {
    try {
      _ensureInitialized();
      final futures = operations.map((op) => op()).toList();
      await Future.wait(futures);
      AppLogger.debug('Batch operations completed');
    } catch (e) {
      AppLogger.error('Failed to execute batch operations', e);
      throw StorageException(
        message: 'Failed to execute batch operations',
        details: e.toString(),
      );
    }
  }
}